﻿using System.Collections.Generic;

namespace Cube.Data
{
    class Cube
    {
        private List<Block> Blocks;
        public Cube()
        {
            Blocks = new List<Block>();
            InitCube3();
        }
        public Cube(List<Block> blocks)
        {
            Blocks = new List<Block>();
            foreach(var block in blocks)
            {
                Blocks.Add(block.Clone());
            }
        }
        public Cube Clone()
        {
            return new Cube(Blocks);
        }
        public ColorVector this[PositionVector index]
        {
            get
            {
                foreach(var block in Blocks)
                {
                    if (block.Position.X == index.X && block.Position.Y == index.Y && block.Position.Z == index.Z)
                    {
                        return block.ColorVector;
                    }
                }
                throw new System.IndexOutOfRangeException();
            }
        }

        public Block this[int index]
        {
            get
            {
                return Blocks[index];
            }
        }

        public int FindCubeByPosition(PositionVector position)
        {
            foreach(var block in Blocks)
            {
                if (block.Position.Equals(position))
                {
                    return Blocks.IndexOf(block);
                }
            }
            return -1;
        }

        public CubeColor[,] GetFace(Faces faceIndex)
        {
            CubeColor[,] face = new CubeColor[3, 3];
            switch (faceIndex)
            {
                case Faces.Up:
                    foreach(var block in Blocks)
                    {
                        if (block.Position.Z == 1)
                        {
                            face[block.Position.Y + 1, block.Position.X + 1] = block.ColorVector.Z;
                        }
                    }
                    break;
                case Faces.Down:
                    foreach(var block in Blocks)
                    {
                        if (block.Position.Z == -1)
                        {
                            face[2 - (block.Position.Y + 1), block.Position.X + 1] = block.ColorVector.Z;
                        }
                    }
                    break;
                case Faces.Front:

                    foreach (var block in Blocks)
                    {
                        if (block.Position.Y == 1)
                        {
                            face[2 - (block.Position.Z + 1), block.Position.X + 1] = block.ColorVector.Y;
                        }
                    }
                    break;
                case Faces.Behind:
                    foreach (var block in Blocks)
                    {
                        if (block.Position.Y == -1)
                        {
                            face[2 - (block.Position.Z + 1), block.Position.X + 1] = block.ColorVector.Y;
                        }
                    }
                    break;
                case Faces.Left:
                    foreach (var block in Blocks)
                    {
                        if (block.Position.X == -1)
                        {
                            face[2 - (block.Position.Z + 1), block.Position.Y + 1] = block.ColorVector.X;
                        }
                    }
                    break;
                case Faces.Right:
                    foreach(var block in Blocks)
                    {
                        if(block.Position.X == 1)
                        {
                            face[2 - (block.Position.Z + 1), 2-(block.Position.Y + 1)] = block.ColorVector.X;
                        }
                    }
                    break;
            }
            return face;
        }

        public void Rotate(Dimention dimention, int step)
        {
            foreach (var block in Blocks)
            {
                block.Rotate(dimention, step);
            }
        }

        public void Rotate(Faces face, int step)
        {
            switch (face)
            {
                case Faces.Up:
                    foreach(var block in Blocks)
                    {
                        if(block.Position.Z == 1)
                        {
                            block.Rotate(Dimention.Z, step);
                        }
                    }
                    break;
                case Faces.Down:
                    foreach(var block in Blocks)
                    {
                        if (block.Position.Z == -1)
                        {
                            block.Rotate(Dimention.Z, step);
                        }
                    }
                    break;
                case Faces.Left:
                    foreach(var block in Blocks)
                    {
                        if(block.Position.X == -1)
                        {
                            block.Rotate(Dimention.X, step);
                        }
                    }
                    break;
                case Faces.Right:
                    foreach (var block in Blocks)
                    {
                        if (block.Position.X == 1)
                        {
                            block.Rotate(Dimention.X, step);
                        }
                    }
                    break;
                case Faces.Front:
                    foreach (var block in Blocks)
                    {
                        if (block.Position.Y == 1)
                        {
                            block.Rotate(Dimention.Y, step);
                        }
                    }
                    break;
                case Faces.Behind:
                    foreach (var block in Blocks)
                    {
                        if (block.Position.Y == -1)
                        {
                            block.Rotate(Dimention.Y, step);
                        }
                    }
                    break;
                case Faces.MF:
                    foreach(var block in Blocks)
                    {
                        if(block.Position.Y == 0)
                        {
                            block.Rotate(Dimention.Y, step);
                        }
                    }
                    break;
                case Faces.MU:
                    foreach (var block in Blocks)
                    {
                        if (block.Position.Z == 0)
                        {
                            block.Rotate(Dimention.Z, step);
                        }
                    }
                    break;
                case Faces.MR:
                    foreach (var block in Blocks)
                    {
                        if (block.Position.X == 0)
                        {
                            block.Rotate(Dimention.X, step);
                        }
                    }
                    break;
            }
        } 

        private void InitCube3()
        {
            //添加中心块
            Blocks.Add(new Block(new PositionVector(0, 1, 0), new ColorVector(CubeColor.None, CubeColor.Blue, CubeColor.None)));
            Blocks.Add(new Block(new PositionVector(0, -1, 0), new ColorVector(CubeColor.None, CubeColor.Green, CubeColor.None)));
            Blocks.Add(new Block(new PositionVector(1, 0, 0), new ColorVector(CubeColor.Red, CubeColor.None, CubeColor.None)));
            Blocks.Add(new Block(new PositionVector(-1, 0, 0), new ColorVector(CubeColor.Orange, CubeColor.None, CubeColor.None)));
            Blocks.Add(new Block(new PositionVector(0, 0, 1), new ColorVector(CubeColor.None, CubeColor.None, CubeColor.Yellow)));
            Blocks.Add(new Block(new PositionVector(0, 0, -1), new ColorVector(CubeColor.None, CubeColor.None, CubeColor.White)));
            //添加棱块
            Blocks.Add(new Block(new PositionVector(1, 0, 1), new ColorVector(CubeColor.Red, CubeColor.None, CubeColor.Yellow)));
            Blocks.Add(new Block(new PositionVector(-1, 0, 1), new ColorVector(CubeColor.Orange, CubeColor.None, CubeColor.Yellow)));
            Blocks.Add(new Block(new PositionVector(0, 1, 1), new ColorVector(CubeColor.None, CubeColor.Blue, CubeColor.Yellow)));
            Blocks.Add(new Block(new PositionVector(0, -1, 1), new ColorVector(CubeColor.None, CubeColor.Green, CubeColor.Yellow)));

            Blocks.Add(new Block(new PositionVector(1, 0, -1), new ColorVector(CubeColor.Red, CubeColor.None, CubeColor.White)));
            Blocks.Add(new Block(new PositionVector(-1, 0, -1), new ColorVector(CubeColor.Orange, CubeColor.None, CubeColor.White)));
            Blocks.Add(new Block(new PositionVector(0, 1, -1), new ColorVector(CubeColor.None, CubeColor.Blue, CubeColor.White)));
            Blocks.Add(new Block(new PositionVector(0, -1, -1), new ColorVector(CubeColor.None, CubeColor.Green, CubeColor.White)));

            Blocks.Add(new Block(new PositionVector(1, 1, 0), new ColorVector(CubeColor.Red, CubeColor.Blue, CubeColor.None)));
            Blocks.Add(new Block(new PositionVector(1, -1, 0), new ColorVector(CubeColor.Red, CubeColor.Green, CubeColor.None)));
            Blocks.Add(new Block(new PositionVector(-1, 1, 0), new ColorVector(CubeColor.Orange, CubeColor.Blue, CubeColor.None)));
            Blocks.Add(new Block(new PositionVector(-1, -1, 0), new ColorVector(CubeColor.Orange, CubeColor.Green, CubeColor.None)));
            //添加角块
            Blocks.Add(new Block(new PositionVector(1, 1, 1), new ColorVector(CubeColor.Red, CubeColor.Blue, CubeColor.Yellow)));
            Blocks.Add(new Block(new PositionVector(1, -1, 1), new ColorVector(CubeColor.Red, CubeColor.Green, CubeColor.Yellow)));
            Blocks.Add(new Block(new PositionVector(-1, 1, 1), new ColorVector(CubeColor.Orange, CubeColor.Blue, CubeColor.Yellow)));
            Blocks.Add(new Block(new PositionVector(-1, -1, 1), new ColorVector(CubeColor.Orange, CubeColor.Green, CubeColor.Yellow)));

            Blocks.Add(new Block(new PositionVector(1, 1, -1), new ColorVector(CubeColor.Red, CubeColor.Blue, CubeColor.White)));
            Blocks.Add(new Block(new PositionVector(1, -1, -1), new ColorVector(CubeColor.Red, CubeColor.Green, CubeColor.White)));
            Blocks.Add(new Block(new PositionVector(-1, 1, -1), new ColorVector(CubeColor.Orange, CubeColor.Blue, CubeColor.White)));
            Blocks.Add(new Block(new PositionVector(-1, -1, -1), new ColorVector(CubeColor.Orange, CubeColor.Green, CubeColor.White)));
        }
    }

    enum Faces
    {
        Front,
        Right,
        Behind,
        Left,
        Up,
        Down,
        MR,
        MU,
        MF
    }
}
